//
// Copyright (c) 2005 BroadVision, Inc. All rights reserved.
//
// This software is copyrighted.  Under the copyright laws, this software
// may not be copied, in whole or in part, without prior written consent
// of BroadVision, Inc. or its assignees.  This software is provided under
// the terms of a license between BroadVision and the recipient, and its
// use is subject to the terms of that license.
//
// This software may be protected by one or more U.S. and International
// patents.  Certain applications of BroadVision One-To-One software are
// covered by U.S. patent 5,710,887.
//
// TRADEMARKS: BroadVision and BroadVision One-To-One are registered
// trademarks of BroadVision, Inc., in the United States and the European
// Community, and are trademarks of BroadVision, Inc., in other
// countries.  The BroadVision logo, is a trademark of BroadVision, Inc.,
// in the United States and other countries. Additionally, IONA and Orbix
// are trademarks of IONA Technologies, Ltd.  RSA, MD5, and RC2 are
// trademarks of RSA Data Security, Inc.
//

package com.broadvision.manage.common.tools.action.user;

import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.Globals;

import com.broadvision.manage.tools.action.BaseAction;
import com.broadvision.portal.services.UserTemplate;
import com.broadvision.portal.services.util.TransferBeanUtils;
import com.broadvision.license2.*;
import com.broadvision.web.util.ViewDynaBean;
import com.broadvision.manage.common.tools.user.UserProfile;
import com.broadvision.manage.common.tools.user.UserSearch;
import com.broadvision.web.servlet.SessionVisitor;
import com.broadvision.system.accesscontrol.client.*;
import com.broadvision.visitor.client.VisitorManager;
import com.broadvision.visitor.client.Visitor;
import com.broadvision.portal.services.PortalVisitor;
import com.broadvision.data.common.DataConstants;

/**
 * Searches users based on criteria, mostly by roles
 */
public class UserSearchByRoleAction extends BaseAction {

  public static final String VIEW_BEAN_NAME = "mtUserSearchView";
  public static final String DTO_BEAN_NAME  = "mtUserSearchDTO";
  public static VisitorManager visitorManager = new VisitorManager();

  /**
   * Implements the action for searching users based on criteria.
   * <p> <p>
   * @param mapping <code>ActionMapping</code> object used to select this instance
   * @param form Optional <code>ActionForm</code> bean for this request (if any)
   * @param request <code>HttpServletRequest</code> object to process
   * @param response <code>HttpServletResponse</code> object to process
   * <p> <p>
   * @return <code>ActionForward</code> instance describing where and how
   * control should be forwarded, or null if the response has already been completed
   * <p> <p>
   * @throws Exception if an error occurs
   */
  public ActionForward processExecute(ActionMapping mapping,
				      ActionForm form,
				      HttpServletRequest request,
				      HttpServletResponse response)
     throws Exception
  {

    try {
      int serviceId = getServiceId(request);
      PortalVisitor agent = getPortalVisitor(request);
      Visitor visitor = agent.getVisitor();

      boolean canEdit = UserProfile.isPermitted(visitor, "Edit");

      if ("userAssignRoles".equalsIgnoreCase(mapping.getParameter())) {
	UserUtils.setP(form, "assignRolesMessage", "userAssignRoles");
      }

      ViewDynaBean view = new ViewDynaBean(VIEW_BEAN_NAME, mapping);
      request.setAttribute(VIEW_BEAN_NAME, view);

      UserUtils.setP(view, "useFullName", new Boolean(!VisitorManager.isUsingFMLName()));
      
      // save allRoles in view

      GenericSectionDB genericSectionDB = new GenericSectionDB();
      List listOfRoles = genericSectionDB.getRolesInSection("/Global/ProcessManagementCenter");

      List listOfRoles_cm = genericSectionDB.getRolesInSection("/Global/ContentManagement");
      if (listOfRoles_cm != null)
          listOfRoles.addAll(listOfRoles_cm);
      
      List globalRoles = new ArrayList();

      for (Iterator it = listOfRoles.iterator(); it.hasNext();) {
	  UserRole userRole = (UserRole) it.next();
	  // to include processManager, not processInstanceManager role
	  // which are not global
	  if (!"ProcessInstanceManager".equals(userRole.getName()) && (!"ProcessModeler".equals(userRole.getName())))
	      globalRoles.add(userRole);
	  /**
	     if (RoleType.GLOBAL == userRole.getRoleType()) {
	     globalRoles.add(userRole);
	     }
	  */
      }
      
      UserUtils.setP(view, "allRoles", globalRoles);

      String searchLetter = request.getParameter("searchLetter");
      boolean searchUsers = ((Boolean)UserUtils.getP(form, "searchUsers")).booleanValue();
      
      if (!searchUsers && 
	  (searchLetter == null || (searchLetter.trim().length() == 0))) {
	  UserUtils.setP(form, "userAlias", ""); 
	  UserUtils.setP(form, "firstName", "");
	  UserUtils.setP(form, "lastName", ""); 
	  return mapping.findForward("success");
      }

      UserSearch userSearch = new UserSearch();
      //
      // to make search service specific, call UserSearch.setServiceId
      // if not service specific, set serviceId to -1
      //
      userSearch.setServiceId(serviceId);
      TransferBeanUtils.copyPropertiesToModel(userSearch, form);
      
      userSearch.setUseFullName(!VisitorManager.isUsingFMLName());
      
      userSearch.setSearchLetter(request.getParameter("searchLetter"));
      
      /**
      // set the sorting from a key in the ApplicationResources file
      if (VisitorManager.isUsingFMLName()) {
	  
	  String firstName = "FIRST_NAME";
	  String middleName = "MIDDLE_NAME";
	  String lastName = "LAST_NAME";
	  
	  String sortOrder = getResources(request, "mc.messages"). getMessage(getLocale(request), 
									      "bp.user.userName.sortOrder",
									      firstName, 
									      middleName,
									      lastName);
	  if (0 == sortOrder.indexOf(firstName)) {
	      userSearch.setSortAttr(firstName);
	  }
	  else if (0 == sortOrder.indexOf(middleName)) {
	      userSearch.setSortAttr(middleName);
	  }
	  else {
	      userSearch.setSortAttr(lastName);
	  }
      }
      */

      String[] roles = userSearch.getRoles();

      long[] matchingVisitorIDs = null;
      Visitor[] matchingVisitors = null;
      int numOfVisitors = 0;

      if ((roles == null) || (roles.length == 0)) {
        // only does search on the user alias
	matchingVisitorIDs = userSearch.popupSearch();
        numOfVisitors = (matchingVisitorIDs == null) ? 0 : matchingVisitorIDs.length;
      }
      else {
        matchingVisitors = userSearch.searchByRole();
	numOfVisitors = (matchingVisitors == null) ? 0 : matchingVisitors.length;
      }

      UserUtils.setP(view, "numOfUsers", new Integer(numOfVisitors));
      
      // pagination support
      
      int countOfResults = numOfVisitors;
      
      // entriesPerPage is always not null
      
      int entriesPerPage = ((Integer) UserUtils.getP(form, "entriesPerPage")).intValue();
      int firstEntry = 0;
      int lastEntry = countOfResults;
      int totalPageNumber = 1;
      int currentPageNumber = 1;
      
      if (countOfResults > entriesPerPage) {
	  
	  // currentPageNumber and totalPageNumber are always not null
	  currentPageNumber = ((Integer) UserUtils.getP(form, "currentPageNumber")).intValue();
	  
	  totalPageNumber = countOfResults / entriesPerPage;
	  if (countOfResults % entriesPerPage > 0) {
	      totalPageNumber++;
	  }
	  // if the entriesPerPage has been increased
	  if (currentPageNumber > totalPageNumber) {
	      currentPageNumber = totalPageNumber;
	  }
	  
	  if (currentPageNumber == 0) {
	      // first page
	      currentPageNumber = 1;
	  }
	  else {
	      firstEntry = (currentPageNumber - 1) * entriesPerPage;
	  }
	  lastEntry = firstEntry + entriesPerPage;
      }
      else {
	  entriesPerPage = countOfResults;
      }
      
      UserUtils.setP(form, "currentPageNumber", new Integer(currentPageNumber));
      UserUtils.setP(form, "totalPageNumber", new Integer(totalPageNumber));
      
      List dtos = new ArrayList(entriesPerPage);
      UserUtils.setP(view, "userList", dtos);
      Visitor v = null;
      
      for (int i = firstEntry; (i < countOfResults) && (i < lastEntry); i++) {
        if ((roles == null) || (roles.length == 0)) {
          try {
	    v = visitorManager.getVisitor(matchingVisitorIDs[i]);
	  } 
	  catch (Exception eex) {
	    // may be inactive
	    continue;
	  }
	}
	else {
	  v = matchingVisitors[i];
	}

	long userId = v.getId();
	ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
	UserUtils.setP(oneDto, "userAlias", v.getUserAlias());      
	
	String formattedName = UserUtils.getFormattedName(v,
							  getResources(request, "mc.messages"), 
							  getLocale(request));
	
	UserUtils.setP(oneDto, "formattedName", formattedName);
	
	UserUtils.setP(oneDto, "city", v.getStringValue("CITY"));
	UserUtils.setP(oneDto, "state", v.getStringValue("STATE"));
	UserUtils.setP(oneDto, "phone", v.getStringValue("BUS_PHONE"));
	UserUtils.setP(oneDto, "email", v.getStringValue("EMAIL"));
	UserUtils.setP(oneDto, "userId", new Long(userId));
	
	UserUtils.setP(oneDto, "canRemoveFromService", new Boolean(PortalVisitor.inService(serviceId, userId)));
	UserUtils.setP(oneDto, "canDelete", new Boolean(true));
	
	// this user can't be deleted. one can't delete oneself as well
	if ("bvadmin".equals(v.getUserAlias()) || (userId == getVisitor(request).getId())) {
          UserUtils.setP(oneDto, "canDelete", Boolean.FALSE);
	}
	
	Hashtable urlParams = new Hashtable();
	urlParams.put("userId", new Long(userId));
	
	UserUtils.setP(oneDto, "urlParams", urlParams);
	
	dtos.add(oneDto);
      } // end of for ... loop
      
      UserUtils.setP(view, "canEdit", new Boolean(UserProfile.isPermitted(visitor, "edit")));
    }
    catch(Exception ex) {
      ex.printStackTrace();
      request.setAttribute(Globals.ERROR_KEY, "error.application");
      return (mapping.findForward("failure"));
    }
    
    return mapping.findForward("success");
  }
}

